package org.andy.kit.lock.redis;

import java.util.concurrent.TimeUnit;

import org.andy.kit.lock.Callback;
import org.andy.kit.lock.LockTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.JedisPool;

/**
 * redis锁模板<br>
 *
 * @author andy
 * @version V1.0
 * @date 18/2/8 下午12:24
 */
public class RedisLockTemplate implements LockTemplate {

    private static final Logger LOG = LoggerFactory.getLogger(RedisLockTemplate.class);

    private JedisPool jedisPool;

    public RedisLockTemplate(JedisPool jedisPool) {
        this.jedisPool = jedisPool;
    }

    @Override
    public Object execute(String lockId, long timeout, Callback callback) {
        RedisReentrantLock redisReentrantLock = null;
        boolean isLock = false;
        try {
            redisReentrantLock = new RedisReentrantLock(jedisPool, lockId);

            // 获取锁
            if (redisReentrantLock.tryLock(new Long(timeout), TimeUnit.MILLISECONDS)) {
                isLock = true;
                // 执行实际任务
                callback.onGetLock();
            } else {
                // 超时处理
                callback.onTimeout();
            }

        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            throw new RuntimeException("execute lock " + lockId + "failure");
        } finally {

            // unlock
            if (isLock){
                redisReentrantLock.unlock();
            }
        }

        return null;
    }
}
